﻿using System;
using System.Collections.Generic;
using System.Linq;
using Atmk.WaterMeter.MIS.Base;
using Atmk.WaterMeter.MIS.Common;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic.Statistics;
using Atmk.WaterMeter.MIS.Commons.Utils;
using Atmk.WaterMeter.MIS.Commons.ViewModels;
using Atmk.WaterMeter.MIS.Datas;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.Entities.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CSharp.RuntimeBinder;
using NLog;

namespace Atmk.WaterMeter.MIS.Controllers
{
    /// <summary>
    ///     账户管理模块
    /// </summary>
    [Authorize]
    public class AccountManageController : BaseApiController
    {
        private readonly TokenHelper _tokenHelper;
        private readonly IBaseInfoLogic _baseStatistcsLogic;
        private readonly IAccountManageLogic _accountManageLogic;
        private static readonly Logger _logger = LogManager.GetCurrentClassLogger();

        /// <inheritdoc />
        public AccountManageController(
            IBaseInfoLogic baseInfoLogic,
            IAccountManageLogic accountManageLogic,
            TokenHelper tokenHelper)
        {
            _baseStatistcsLogic = baseInfoLogic;
            _accountManageLogic = accountManageLogic;
            _tokenHelper = tokenHelper;
        }

        /// <summary>
        ///     查询账户信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Manange/Select")]
        public IActionResult SelectAccount([FromBody] dynamic obj)
        {
            //验证用户信息 获取配置
            var token = _tokenHelper.GetTokenByHttpContext();
            var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
            try
            {
                //获取所有查询条件
                var searchType = obj.searchType.ToString();
                var searchValue = obj.searchValue.ToString();
                string aid = obj.aid.ToString();
                var page = Convert.ToInt32(obj.page.ToString());
                var areaId = token.payload.areaid;

                //var result = _accountManageLogic.SelectAccount(areaId, aid, page, pageSize, out int count, searchType, searchValue);
                using (var context = ContextBuilder.Build())
                {
                    List<District> total_districts = null;
                    if (string.IsNullOrWhiteSpace(aid)) 
                    {
                        total_districts = context.District.Where(m => m.ProjectId == areaId && m.NodeType == 2).ToList();
                    }
                    else
                    {
                        total_districts = context.District.Where(m => m.Id == aid).ToList();
                    }
                    //total_districts = getNodeNext(Projects2district, aid, Projects2district, new List<District>());
                    var districts_ids = total_districts.Select(m1 => m1.Id.ToString());
                    List<Owner> total_owners = context.Owner.Where(o => districts_ids.Contains(o.DistrictId)).OrderBy(m=>m.Name).ToList();
                    //var owners_ids = total_owners.Select(m1 => m1.Id.ToString());
                    var result = total_owners.Select(m => (object)new
                    {
                        districtId = m.DistrictId, //片区Id
                        districtName = total_districts.FirstOrDefault(m1=>m1.Id.ToString()==m.DistrictId)?.Name, //片区名称
                        ownerId = m.Id.ToString(), //业主Id
                        ownerName = m.Name, //业主名称
                        houseNumber = m.HouseNumber, //门牌号           
                        mobile = m.Mobile, //手机号码
                        accountId= "", //账户id
                        balance=context.OrderDetail.Where(m1=>m1.OwnerId==m.Id.ToString()).Sum(m1=>m1.Money), //账户余额
                        arrears= 0
                    });

                    //获取分页数据
                    var pageList = PaginatedList<object>.Create(result.ToList(), page, pageSize);

                    return Ok(new
                    {
                        errcode = 0,
                        msg = "ok",
                        data = new
                        {
                            total = total_owners.Count,
                            pageSize,
                            list = pageList
                        }
                    });
                }
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取账户数据错误,错误:{e.Message}"
                });
            }
        }

       
        private List<District> getNodeNext(List<District> districts, string id, List<District> districtsOld, List<District> result_last_District)
        {

            if (districts.Any(m => m.Id.ToString() == id && m.NodeType == 2))
            {
                result_last_District.AddRange(districts.Where(m => m.Id.ToString() == id));
            }
            else
            {
                foreach (var item in districtsOld.Where(m => m.Parent == id))
                {
                    getNodeNext(districtsOld.Where(m => m.Parent == id).ToList(), item.Id.ToString(), districtsOld, result_last_District);
                }
            }
            return result_last_District;
        }

        /// <summary>
        ///     充值
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Manange/Recharge")]
        public IActionResult RechargeAccount([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            try
            {
                //获取配置
                string ownerId = obj.ownerId.ToString();
                decimal refill = Convert.ToDecimal(obj.refill); //实收金额
                //_logger.LogError($"接收应付金额{payment},上次余额{lastBalance},实收金额{refill}");

                using (var context = new atmk_wmdb_devContext())
                {
                    var order = new OrderDetail()
                    {
                        Money = refill,
                        CostType = 0,                                    //0充值1水表扣费2退费
                        RechargeChannels = "平台充值",      //充值渠道
                        OwnerId = ownerId,
                        CreateTime = DateTime.Now
                    };
                    context.OrderDetail.Add(order);
                    var result = context.SaveChanges();
                    if (result > 0)
                    {
                        return Ok(new
                        {
                            errcode = 0,
                            msg = "ok"
                        });
                    }
                    else
                    {
                        _logger.Fatal("订单充值异常，保存记录失败");
                        return Ok(new
                        {
                            errcode = 1,
                            msg = "订单充值异常"
                        });
                    }

                }
                //var result = _accountManageLogic.RechargeAccount(token.payload.id, token.payload.name, ownerId, accountId, payment, lastBalance, refill, out Exception exception);
                //if (!result)
                //    return Ok(
                //        new
                //        {
                //            errcode = 1,
                //            msg = $"充值失败:{exception.Message}"
                //        });

            }
            catch (Exception e)
            {
                _logger.Fatal($"充值失败,错误：{e.Message}");
                return Ok(new
                {
                    errcode = 1,
                    msg = $"充值失败,错误：{e.Message}"
                });
            }
        }

        /// <summary>
        ///     退费
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Manange/Returns")]
        public IActionResult ReturnsAccount([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            //获取配置
            var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
            try
            {
                //获取配置
                string ownerId = obj.ownerId.ToString();
                string accountId = obj.accountId.ToString();
                var returns = Simple.DecimalConvertString(obj.returns.ToString());
                var result = _accountManageLogic.ReturnsAccount(token.payload.id, ownerId, accountId, returns, out Exception exception);
                if (accountId.Trim().Length == 0)
                    return Ok(
                        new
                        {
                            errcode = 1,
                            msg = "退费失败:该账户没有金额"
                        });

                if (!result)
                    return Ok(
                        new
                        {
                            errcode = 1,
                            msg = $"退费失败:{exception.Message}"
                        });
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok"
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"退费操作错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        ///     销户
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Manange/Closing")]
        public IActionResult ClosingAccount([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            try
            {
                //获取配置
                string ownerId, accountId;
                try
                {
                    ownerId = obj.ownerId.ToString();
                    accountId = obj.accountId.ToString();
                }
                catch (RuntimeBinderException re)
                {
                    _logger.Fatal(re.Message.ToString());
                    return Ok(
                        new
                        {
                            errcode = 1,
                            msg = "参数错误"
                        });
                }

                var result = _accountManageLogic.ClosingAccount(token.payload.id, token.payload.name, ownerId, accountId, out var message);
                if (!result)
                    return Ok(
                        new
                        {
                            errcode = 1,
                            msg = $"销户失败{message}"
                        });
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok"
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"销户失败"
                });
            }
        }

        /// <summary>
        ///     查询指定账户扣费信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Manange/SelectPayment")]
        public IActionResult SelectPayment([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //获取配置
            var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
            try
            {
                //获取所有查询条件
                var aid = obj.aid.ToString();
                var page = Convert.ToInt32(obj.page.ToString());
                //获取配置
                string ownerId = obj.ownerId.ToString();
                string accountId = obj.accountId.ToString();
                var result = _accountManageLogic.SelectPayment(token.payload.id, aid, page, pageSize,
                    out int count, ownerId, accountId);
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok",
                    data = new
                    {
                        total = count,
                        pageSize,
                        list = result
                    }
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取扣费数据错误,错误:{e.Message}"
                });
            }
        }
        /// <summary>
        /// 扣费类型集合获取
        /// </summary>
        /// <returns></returns>
        [HttpGet("/api/{X-Version}/Account/Payment/PaymentType")]
        public IActionResult PaymentTypeList()
        {
            var token = _tokenHelper.GetTokenByHttpContext();

            BaseResult baseResult;
            try
            {
                baseResult = new EnumListResult
                {
                    errcode = 0,
                    msg = "ok",
                    list = Enum.GetNames(typeof(AmountChangedDownMode)).ToList()
                };
                return Ok(baseResult);
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                baseResult = new BaseResult
                {
                    errcode = 1,
                    msg = "获取失败"
                };
            }
            return Ok(baseResult);
        }

        /// <summary>
        ///     查询扣费记录
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Payment/Select")]
        public IActionResult SelectPayments([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            //获取配置
            var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);

            string searchType, searchValue, aid;
            int page;
            int paymentType;
            bool dts, dte;
            DateTime startTime, endTime;
            try
            {
                //获取所有查询条件
                searchType = obj.searchType.ToString();
                searchValue = obj.searchValue.ToString();
                aid = obj.aid.ToString();
                page = Convert.ToInt32(obj.page.ToString());
                paymentType = Convert.ToInt32(obj.paymentType.ToString());
                //时间--转换确认
                dts = DateTime.TryParse(obj.startTime.ToString(), out startTime);
                dte = DateTime.TryParse(obj.endTime.ToString(), out endTime);
            }
            catch (RuntimeBinderException re)
            {
                _logger.Fatal(re.Message.ToString());
                return Ok(new BaseResult { errcode = 0, msg = "参数错误" });
            }
            try
            {


                if (!dts || !dte)
                    return Ok(new
                    {
                        errcode = 1,
                        msg = "时间格式错误"
                    });
                var result = _accountManageLogic.SelectPayment(token.payload.id, aid, page, pageSize, startTime,
                    endTime, paymentType, out var count, searchType, searchValue);
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok",
                    data = new
                    {
                        total = count,
                        pageSize,
                        list = result
                    }
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取扣费数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        ///     费用减免
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Payment/FeeDerate")]
        public IActionResult FeeDerate([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            try
            {
                //获取配置
                string userId = obj.userId.ToString();
                string accountId = obj.accountId.ToString();
                decimal money = Simple.DecimalConvertString(obj.money.ToString());
                var result = _accountManageLogic.FeeDerate(token, userId, accountId, money, out Exception exception);
                if (!result)
                    return Ok(
                        new
                        {
                            errcode = 1,
                            msg = $"减免费用失败:{exception.Message}"
                        });
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok"
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"费用减免失败,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        ///     查询充值记录
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Refill/Select")]
        public IActionResult SelectRefills([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            //获取配置
            var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
            try
            {
                //获取所有查询条件
                var searchType = obj.searchType.ToString();
                var searchValue = obj.searchValue.ToString();
                var aid = obj.aid.ToString();
                var page = Convert.ToInt32(obj.page.ToString());
                //时间--转换确认
                var dts = DateTime.TryParse(obj.startTime.ToString(), out DateTime startTime);
                var dte = DateTime.TryParse(obj.endTime.ToString(), out DateTime endTime);
                if (!dts || !dte)
                    return Ok(new
                    {
                        errcode = 1,
                        msg = "时间格式错误"
                    });
                var result = _accountManageLogic.SelectRefills(token.payload.areaid, aid, page, pageSize, startTime,
                    endTime, out int count, searchType, searchValue);
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok",
                    data = new
                    {
                        total = count,
                        pageSize,
                        list = result
                    }
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取扣费数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        ///     撤销充值记录
        /// </summary>
        /// <returns></returns>
        [HttpPost("/api/{X-Version}/Account/Refill/Revert")]
        public IActionResult RevertRefill([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            try
            {
                //获取配置
                string ownerId = obj.ownerId.ToString();
                string accountId = obj.accountId.ToString();
                string refillId = obj.refillId.ToString();
                var result = _accountManageLogic.RevertRefill(token.payload.id, ownerId, accountId, refillId, out Exception exception);
                if (!result)
                    return Ok(
                        new
                        {
                            errcode = 1,
                            msg = $"撤销充值失败:{exception.Message}"
                        });
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok"
                });
            }
            catch (Exception e)
            {
                _logger.Fatal(e.Message.ToString());
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取扣费数据错误,错误:{e.Message}"
                });
            }
        }
    }
}